package com.fish.web.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fish.common.annotation.RequiresPermission;
import com.fish.common.result.ImportResult;
import com.fish.common.result.Result;
import com.fish.model.dto.UserAddDTO;
import com.fish.model.dto.UserLoginDTO;
import com.fish.model.dto.UserRegisterDTO;
import com.fish.model.dto.UserUpdateDTO;
import com.fish.model.entity.User;
import com.fish.model.vo.FileInfoVO;
import com.fish.model.vo.LoginVO;
import com.fish.model.vo.UserInfoVO;
import com.fish.model.vo.UserVO;
import com.fish.service.FileUploadService;
import com.fish.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletResponse;

/**
 * 用户Controller
 */
@Tag(name = "用户管理", description = "用户相关接口，包括用户注册、登录、信息查询、增删改查等")
@Slf4j
@RestController
@RequestMapping("/api/user")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private FileUploadService fileUploadService;
    
    /**
     * 用户注册
     */
    @Operation(summary = "用户注册", description = "用户名密码注册新用户")
    @PostMapping("/register")
    public Result<UserVO> register(@Validated @RequestBody UserRegisterDTO registerDTO) {
        log.info("用户注册请求，用户名：{}", registerDTO.getUsername());
        UserVO userVO = userService.register(registerDTO);
        return Result.success("注册成功", userVO);
    }
    
    /**
     * 用户登录
     */
    @Operation(summary = "用户登录", description = "用户名密码登录")
    @PostMapping("/login")
    public Result<LoginVO> login(@Validated @RequestBody UserLoginDTO loginDTO) {
        log.info("用户登录请求，用户名：{}", loginDTO.getUsername());
        LoginVO loginVO = userService.login(loginDTO);
        return Result.success("登录成功", loginVO);
    }
    
    /**
     * 获取用户信息（根据用户ID）
     */
    @GetMapping("/{userId:\\d+}")
    public Result<UserVO> getUserById(@PathVariable Long userId) {
        log.info("获取用户信息，用户ID：{}", userId);
        UserVO userVO = userService.getUserById(userId);
        return Result.success(userVO);
    }
    
    /**
     * 获取用户信息（根据用户名）
     */
    @GetMapping("/username/{username}")
    public Result<UserVO> getUserByUsername(@PathVariable String username) {
        log.info("获取用户信息，用户名：{}", username);
        UserVO userVO = userService.getUserByUsername(username);
        return Result.success(userVO);
    }
    
    /**
     * 获取用户完整信息（包含角色、权限、菜单）
     */
    @GetMapping("/info/{userId}")
    public Result<UserInfoVO> getUserInfo(@PathVariable Long userId) {
        log.info("获取用户完整信息，用户ID：{}", userId);
        UserInfoVO userInfo = userService.getUserInfoWithPermissions(userId);
        return Result.success(userInfo);
    }
    
    /**
     * 分页查询用户列表
     */
    @Operation(summary = "分页查询用户列表", description = "分页查询用户列表，支持用户名模糊搜索")
    @Parameters({
        @Parameter(name = "current", description = "当前页码", example = "1"),
        @Parameter(name = "size", description = "每页大小", example = "10"),
        @Parameter(name = "username", description = "用户名（模糊搜索）", required = false)
    })
    @GetMapping("/list")
    @RequiresPermission("system:user:list")
    public Result<Page<UserVO>> getUserList(
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size,
            @RequestParam(required = false) String username
    ) {
        log.info("分页查询用户列表，current：{}，size：{}，username：{}", current, size, username);
        Page<UserVO> page = userService.getUserList(current, size, username);
        return Result.success(page);
    }
    
    /**
     * 添加用户
     */
    @PostMapping("/add")
    @RequiresPermission("system:user:add")
    @com.fish.common.annotation.OperationLog("添加用户")
    public Result<UserVO> addUser(@Validated @RequestBody UserAddDTO addDTO) {
        log.info("添加用户，用户名：{}", addDTO.getUsername());
        UserVO userVO = userService.addUser(addDTO);
        return Result.success("添加成功", userVO);
    }
    
    /**
     * 更新用户
     */
    @PutMapping("/update")
    @RequiresPermission("system:user:edit")
    @com.fish.common.annotation.OperationLog("更新用户")
    public Result<UserVO> updateUser(@Validated @RequestBody UserUpdateDTO updateDTO) {
        log.info("更新用户，用户ID：{}", updateDTO.getId());
        UserVO userVO = userService.updateUser(updateDTO);
        return Result.success("更新成功", userVO);
    }
    
    /**
     * 删除用户
     */
    @DeleteMapping("/delete/{userId}")
    @RequiresPermission("system:user:delete")
    @com.fish.common.annotation.OperationLog("删除用户")
    public Result<Void> deleteUser(@PathVariable Long userId) {
        log.info("删除用户，用户ID：{}", userId);
        userService.deleteUser(userId);
        return Result.success("删除成功", null);
    }
    
    /**
     * 上传用户头像
     */
    @PostMapping("/avatar/upload/{userId}")
    @com.fish.common.annotation.OperationLog("上传头像")
    public Result<UserVO> uploadAvatar(
            @PathVariable Long userId,
            @RequestParam("file") MultipartFile file) {
        log.info("上传用户头像，用户ID：{}", userId);
        
        // 上传文件到MinIO
        FileInfoVO fileInfo = fileUploadService.upload(file, "avatars", "minio");
        
        // 更新用户头像
        UserUpdateDTO updateDTO = new UserUpdateDTO();
        updateDTO.setId(userId);
        updateDTO.setAvatar(fileInfo.getFileUrl());
        
        UserVO userVO = userService.updateUser(updateDTO);
        return Result.success("头像上传成功", userVO);
    }
    
    /**
     * 更新用户头像URL
     */
    @PutMapping("/avatar/{userId}")
    @com.fish.common.annotation.OperationLog("更新头像")
    public Result<UserVO> updateAvatar(
            @PathVariable Long userId,
            @RequestParam String avatarUrl) {
        log.info("更新用户头像URL，用户ID：{}", userId);
        
        UserUpdateDTO updateDTO = new UserUpdateDTO();
        updateDTO.setId(userId);
        updateDTO.setAvatar(avatarUrl);
        
        UserVO userVO = userService.updateUser(updateDTO);
        return Result.success("头像更新成功", userVO);
    }
    
    /**
     * 健康检查
     */
    @GetMapping("/health")
    public Result<String> health() {
        return Result.success("User service is running");
    }
    
    /**
     * 搜索用户（用于聊天）
     */
    @GetMapping("/search")
    public Result<java.util.List<UserVO>> searchUsers(@RequestParam String keyword) {
        log.info("搜索用户，关键词：{}", keyword);
        java.util.List<UserVO> users = userService.searchUsers(keyword);
        return Result.success(users);
    }

    /**
     * 导出用户列表
     */
    @Operation(summary = "导出用户列表", description = "导出用户列表为Excel文件")
    @Parameter(name = "username", description = "用户名（筛选条件）", required = false)
    @GetMapping("/export")
    @RequiresPermission("system:user:export")
    @com.fish.common.annotation.OperationLog("导出用户")
    public void exportUserList(
            HttpServletResponse response,
            @RequestParam(required = false) String username) {
        log.info("导出用户列表，筛选条件 username: {}", username);
        userService.exportUserList(response, username);
    }

    /**
     * 下载用户导入模板
     */
    @GetMapping("/template")
    @RequiresPermission("system:user:import")
    public void downloadTemplate(HttpServletResponse response) {
        log.info("下载用户导入模板");
        userService.downloadTemplate(response);
    }

    /**
     * 导入用户数据
     */
    @Operation(summary = "导入用户数据", description = "通过Excel文件批量导入用户数据")
    @Parameter(name = "file", description = "Excel文件（.xlsx或.xls格式）", required = true, content = @Content(mediaType = "multipart/form-data"))
    @PostMapping("/import")
    @RequiresPermission("system:user:import")
    @com.fish.common.annotation.OperationLog("导入用户")
    public Result<ImportResult<User>> importUserData(@RequestParam("file") MultipartFile file) {
        log.info("导入用户数据，文件名: {}", file.getOriginalFilename());
        
        if (file.isEmpty()) {
            return Result.error("上传文件为空");
        }
        
        if (!file.getOriginalFilename().endsWith(".xlsx") && !file.getOriginalFilename().endsWith(".xls")) {
            return Result.error("请上传Excel文件（.xlsx或.xls格式）");
        }
        
        ImportResult<User> result = userService.importUserData(file);
        
        if (result.isAllSuccess()) {
            return Result.success("导入成功，共导入 " + result.getSuccessCount() + " 条数据", result);
        } else {
            return Result.success("导入完成，成功 " + result.getSuccessCount() + " 条，失败 " + result.getFailureCount() + " 条", result);
        }
    }
}